﻿using DevExpress.LookAndFeel;
using DevExpress.XtraEditors;
using MesProjectWinform.Entity.Request;
using MesProjectWinform.Helper;
using MesProjectWinform.Public;
using MesProjectWinform.Public.Common;
using MesProjectWinform.WareHouse.Entity;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;

namespace MesProjectWinform.WareHouse.Form.货位库区
{
    public partial class Form_ShelvesAdd : DevExpress.XtraEditors.XtraForm
    {
        public Form_ShelvesAdd()
        {
            InitializeComponent();
            // 窗体显示后事件
            this.Shown += Form_ShelvesAdd_Shown;
        }

        public bool UpdateType = false;

        // 使用Shelves类来接收数据
        public Shelves CurrentShelves { get; set; }

        private async void Form_ShelvesAdd_Load(object sender, EventArgs e)
        {
            // 加载仓库类型下拉框数据
            lookUpWHType();

            if (UpdateType)
            {
                // 新增模式
                this.Text = "新增货架库区";
                BtnAdd.Text = "新增";
                // 直接异步获取编码并设置到文本框 - 不使用Task.Run
                string code = await GetCode();
                ShelvesId.Text = code;
            }
            else
            {
                // 修改模式
                this.Text = "修改货架库区";
                BtnAdd.Text = "保存";

                // 绑定传入的数据到控件
                if (CurrentShelves != null)
                {
                    // 填充表单控件
                    ShelvesId.Text = CurrentShelves.Shelvesid;
                    ShelvesName.Text = CurrentShelves.Shelvesname;
                    Memo.Text = CurrentShelves.Memo;
                }
            }
        }

        /// <summary>
        /// 窗体显示后事件 - 确保编码显示
        /// </summary>
        private async void Form_ShelvesAdd_Shown(object sender, EventArgs e)
        {
            // 仅在新增模式且编码为空时重新获取
            if (UpdateType && string.IsNullOrEmpty(ShelvesId.Text))
            {
                try
                {
                    System.Diagnostics.Debug.WriteLine("窗体显示后，编码为空，重新获取...");
                    string code = await GetCode();
                    ShelvesId.Text = code;
                    System.Diagnostics.Debug.WriteLine($"重新获取的编码: {code}");
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"窗体显示后获取编码异常: {ex.Message}");
                }
            }
        }
        private async Task<string> GetCode()
        {
            try
            {
                // 显示等待光标
                Cursor = Cursors.WaitCursor;

                // 添加调试输出

                string codePrefix = DataConverHelper.GetPrefix(CodeType.Area);

                // 首先尝试直接生成一个新编码作为备选
                string fallbackCode = DataConverHelper.GenerateCode(CodeType.Area);

                try
                {
                    // 调用API获取最新编码
                    string apiUrl = "WareHouse/BasicInfo/GetCode?Type=" + codePrefix;
                    HttpClientHelper helper = new HttpClientHelper();
                    string json = helper.RequestUrlNew(RequestType.Get, apiUrl, null);

                    if (string.IsNullOrEmpty(json))
                    {
                        return fallbackCode;
                    }

                    ApiResult<TypeCodeModel> typeModel = JsonConvert.DeserializeObject<ApiResult<TypeCodeModel>>(json);

                    if (typeModel == null)
                    {
                        return fallbackCode;
                    }


                    if (typeModel.Data == null)
                    {
                        return fallbackCode;
                    }

                    string lastCode = typeModel.Data.Code;

                    if (string.IsNullOrEmpty(lastCode))
                    {
                        return fallbackCode;
                    }

                    // 获取数字部分（后六位或全部，如果不足六位）
                    string numberPart;
                    string prefixPart;

                    // 提取数字部分和前缀部分
                    if (lastCode.Length >= 5)
                    {
                        // 如果编码长度超过5位，提取最后5位作为数字部分，其余作为前缀
                        numberPart = lastCode.Substring(lastCode.Length - 5);
                        prefixPart = lastCode.Substring(0, lastCode.Length - 5);
                    }
                    else
                    {
                        // 如果编码长度不足5位，就用整个编码作为数字部分，前缀为空
                        numberPart = lastCode;
                        prefixPart = "";
                    }

                    // 尝试解析为数字并自增1
                    if (int.TryParse(numberPart, out int lastNumber))
                    {
                        // 获取当前日期字符串
                        string currentDateStr = DateTime.Now.ToString("yyMMdd");
                        string dateInPrefix = "";

                        // 检查前缀中是否包含日期信息
                        if (prefixPart.Length >= 8 && prefixPart.StartsWith(codePrefix))
                        {
                            dateInPrefix = prefixPart.Substring(2, 6);
                        }

                        // 如果前缀中的日期与当前日期不同，或者前缀不合规范，则重置编号并使用新日期
                        if (string.IsNullOrEmpty(prefixPart) || !prefixPart.StartsWith(codePrefix) ||
                            (dateInPrefix != currentDateStr && !string.IsNullOrEmpty(dateInPrefix)))
                        {
                            // 新的一天，编号从1开始
                            prefixPart = codePrefix + currentDateStr;
                            lastNumber = 1; // 重置为1
                        }
                        else
                        {
                            // 同一天，编号递增
                            lastNumber++;
                        }

                        // 数字部分解析成功，确保是5位数（前面补0）
                        string sixDigitNumber = lastNumber.ToString("D5");

                        // 组合新编码
                        string newCode = prefixPart + sixDigitNumber;
                        return newCode;
                    }
                    else
                    {
                        return fallbackCode;
                    }
                }
                catch (Exception ex)
                {
                    return fallbackCode;
                }
            }
            finally
            {
                // 恢复光标
                Cursor = Cursors.Default;
            }
        }
        /// <summary>
        /// 下拉框仓库填充
        /// </summary>
        public async void lookUpWHType()
        {
            try
            {
                HttpClientHelper helper = new HttpClientHelper();
                string json = helper.RequestUrlNew(RequestType.Get, "WareHouse/WareHouse/GetWareHouse", null);// await APIClient.CallApiAsync("WareHouse/WareHouse/GetWareHouse", HttpMethod.GET);
                // 确保返回的JSON数据不为空
                if (string.IsNullOrEmpty(json))
                {
                    MessageBox.Show("获取仓库数据失败，返回数据为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // 解析JSON数据
                ApiPaging<List<WareHouses>> model = JsonConvert.DeserializeObject<ApiPaging<List<WareHouses>>>(json);

                // 检查解析后的数据
                if (model == null || model.Data == null || model.Data.Count == 0)
                {
                    MessageBox.Show("获取仓库数据失败，数据为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // 配置LookUpEdit控件
                LUType.Properties.ValueMember = "WHId";
                LUType.Properties.DisplayMember = "Warehousename";
                LUType.Properties.DataSource = model.Data;

                // 配置列显示
                LUType.Properties.Columns.Clear();
                LUType.Properties.Columns.Add(new DevExpress.XtraEditors.Controls.LookUpColumnInfo("Warehouseid", "仓库编号"));
                LUType.Properties.Columns.Add(new DevExpress.XtraEditors.Controls.LookUpColumnInfo("Warehousename", "仓库名称"));
                LUType.Properties.Columns.Add(new DevExpress.XtraEditors.Controls.LookUpColumnInfo("WHId", "仓库主键编码"));
                LUType.Properties.Columns["WHId"].Visible = false;
                // 设置显示格式
                LUType.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;

                // 自定义显示文本
                LUType.CustomDisplayText += (s, e) =>
                {
                    if (e.Value != null)
                    {
                        string warehouseId = e.Value.ToString();
                        var warehouse = model.Data.FirstOrDefault(w => w.Warehouseid == warehouseId);
                        if (warehouse != null)
                        {
                            e.DisplayText = $"{warehouse.Warehouseid}|{warehouse.Warehousename}";
                        }
                    }
                };

                //// 如果有数据，选择第一项
                //if (model.Data.Count > 0 && UpdateType)
                //{
                //    LUType.ItemIndex = 0;
                //}

                // 如果是编辑模式且有当前数据，设置选中的值
                if (!UpdateType && CurrentShelves != null && !string.IsNullOrEmpty(CurrentShelves.Warehouseid))
                {
                    LUType.EditValue = CurrentShelves.Warehouseid;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载仓库数据时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 新增或修改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void BtnAdd_Click(object sender, EventArgs e)
        {
            // 防止重复点击
            BtnAdd.Enabled = false;
            BtnClose.Enabled = false;

            // 记录操作开始时间，用于防止重复提交
            string requestId = Guid.NewGuid().ToString();

            try
            {
                // 显示等待光标
                Cursor = Cursors.WaitCursor;

                // 检查必填字段是否有值
                string errorMessage = Check();
                if (!string.IsNullOrEmpty(errorMessage))
                {
                    MessageBox.Show(errorMessage, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                // 验证编码是否已被占用（并发检查）
                bool isCodeAvailable = await CheckCodeAvailability(ShelvesId.Text.Trim());
                if (!isCodeAvailable && UpdateType) // 只在新增模式下检查
                {
                    MessageBox.Show("货架编码已被占用，请刷新后重试", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                Shelves model = new Shelves();

                // 如果是修改模式，使用传入对象的ID
                if (!UpdateType && CurrentShelves != null)
                {
                    model.SHId = CurrentShelves.SHId;
                    model.WHId = CurrentShelves.WHId;
                    model.CreatedBy = CurrentShelves.CreatedBy;
                    model.CreatedTime = CurrentShelves.CreatedTime;
                    model.Shelvesid = CurrentShelves.Shelvesid; // 保持原编码，防止修改
                }
                else
                {
                    model.SHId = 0;
                    model.CreatedTime = DateTime.Now;
                    model.CreatedBy = RequestUser.CurrentUser.UserId;// "00";
                    model.Shelvesid = ShelvesId.Text.Trim();
                }

                //model.Shelvesid = ShelvesId.Text;
                model.Shelvesname = ShelvesName.Text;
                model.WHId = long.Parse(LUType.EditValue.ToString());

                // 获取选中仓库的名称
                if (LUType.EditValue != null && LUType.Properties.DataSource is List<WareHouses> warehouses)
                {
                    var selectedWarehouse = warehouses.FirstOrDefault(w => w.WHId == model.WHId);
                    if (selectedWarehouse != null)
                    {
                        model.WarehouseName = selectedWarehouse.Warehousename;
                        model.Warehouseid = selectedWarehouse.Warehouseid;
                    }
                }

                model.Memo = Memo.Text;
                model.UpdatedBy = "00"; // 当前用户
                model.UpdatedTime = DateTime.Now;
                model.IsEnable = true;
                
                // 将对象序列化为JSON
                string postData = JsonConvert.SerializeObject(model);
                
                // 添加请求ID，用于防止重复提交
                Dictionary<string, string> headers = new Dictionary<string, string>
                {
                    { "X-Request-ID", requestId },
                    { "X-Client-Timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") }
                };

                int maxRetries = 3;
                int retryCount = 0;
                bool success = false;
                
                while (!success && retryCount < maxRetries)
                {
                    try
                    {
                        HttpClientHelper helper = new HttpClientHelper();
                        // 根据操作类型选择API
                        string url = UpdateType ? "WareHouse/Shelves/AddShelves" : "WareHouse/Shelves/UpdateShelves";
                        string json = helper.RequestUrlNew(RequestType.Post, url, postData);
                        ApiResult<int> baseModel = JsonConvert.DeserializeObject<ApiResult<int>>(json);
                        
                        if (baseModel.Code == ApiEnums.Success)
                        {
                            // 更新编码记录
                            await UpdateCode();

                            string message = UpdateType ? "添加成功" : "修改成功";
                            MessageBox.Show(message, "操作成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            this.DialogResult = DialogResult.OK;

                            // 标记成功
                            success = true;

                            // 关闭窗口
                            this.Close();
                        }
                        else
                        {
                            // 检查是否是因为并发冲突导致的失败
                            if (baseModel.Code == ApiEnums.Error)
                            {
                                retryCount++;
                                if (retryCount < maxRetries)
                                {
                                    // 等待一段时间后重试
                                    await Task.Delay(1000 * retryCount); // 逐次增加等待时间
                                    continue;
                                }
                            }

                            MessageBox.Show(baseModel.Message, "操作失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        retryCount++;
                        if (retryCount >= maxRetries)
                        {
                            MessageBox.Show("保存数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            break;
                        }

                        // 等待一段时间后重试
                        await Task.Delay(1000 * retryCount);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("保存数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // 恢复按钮状态
                BtnAdd.Enabled = true;
                BtnClose.Enabled = true;

                // 恢复光标
                Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 检查货架编码是否可用
        /// </summary>
        /// <param name="code">待检查的编码</param>
        /// <returns>编码是否可用</returns>
        private async Task<bool> CheckCodeAvailability(string code)
        {
            try
            {
                HttpClientHelper helper = new HttpClientHelper();
                // 调用API检查编码是否可用
                string url = $"WareHouse/Shelves/GetShelvesID?ShelvesID={Uri.EscapeDataString(code)}";
                string json = helper.RequestUrlNew(RequestType.Get, url, null);
                ApiResult<int> result = JsonConvert.DeserializeObject<ApiResult<int>>(json);

                // 返回true表示编码可用，false表示编码已被占用
                return result.Code == ApiEnums.Success;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"检查编码可用性时发生异常: {ex.Message}");
                // 出现异常时，假定编码可用，让后续流程继续（后端会再次检查）
                return true;
            }
        }

        /// <summary>
        /// 更新编码记录
        /// </summary>
        public async Task UpdateCode()
        {
            try
            {
                // 根据操作类型选择API
                string url = "WareHouse/BasicInfo/UpdateCode";
                TypeCodeModel model = new TypeCodeModel();
                model.Code = ShelvesId.Text;
                model.CodeType = DataConverHelper.GetPrefix(CodeType.Area);
                model.CodeTypeName = "库区";
                string postData = JsonConvert.SerializeObject(model);

                // 设置重试次数
                int maxRetries = 3;
                int retryCount = 0;
                bool success = false;

                while (!success && retryCount < maxRetries)
                {
                    try
                    {
                        HttpClientHelper helper = new HttpClientHelper();
                        string json = helper.RequestUrlNew(RequestType.Put, url, postData);
                        ApiResult<int> baseModel = JsonConvert.DeserializeObject<ApiResult<int>>(json);

                        if (baseModel != null && baseModel.Code == ApiEnums.Success)
                        {
                            success = true;
                            return;
                        }

                        // 如果失败，尝试重试
                        retryCount++;
                        if (retryCount < maxRetries)
                        {
                            await Task.Delay(1000 * retryCount);
                        }
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine($"更新编码记录时发生异常: {ex.Message}");
                        retryCount++;
                        if (retryCount < maxRetries)
                        {
                            await Task.Delay(1000 * retryCount);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"更新编码记录失败: {ex.Message}");
                // 这里选择不抛出异常，因为即使编码记录更新失败，主业务流程已经完成
            }
        }

        /// <summary>
        /// 关闭页面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// 检查是否有未填数据
        /// </summary>
        public string Check()
        {
            List<string> emptyFields = new List<string>();

            // 检查货架编号
            if (string.IsNullOrWhiteSpace(ShelvesId.Text))
            {
                emptyFields.Add("货架编号");
            }

            // 检查货架名称
            if (string.IsNullOrWhiteSpace(ShelvesName.Text))
            {
                emptyFields.Add("货架名称");
            }

            // 检查所属仓库
            if (LUType.EditValue == null || string.IsNullOrWhiteSpace(LUType.EditValue.ToString()))
            {
                emptyFields.Add("所属仓库");
            }

            // 如果有空字段，返回错误消息
            if (emptyFields.Count > 0)
            {
                return $"操作失败，以下字段不能为空：{string.Join("、", emptyFields)}";
            }

            // 所有字段都已填写
            return string.Empty;
        }
    }
}